/*
 * ArrayList.cpp
 *
 *  Created on: Mar 25, 2014
 *      Author: Anthony Varghese
 */

#include <iostream>

using std::cout;
using std::endl;

#include "ArrayList.h"

namespace cs237list {

ArrayList::ArrayList() : size(0), capacity(DEFAULT_SIZE) {
//	cout << "Default constructor for ArrayList" << endl;
	store = new Node[ DEFAULT_SIZE ];
}

ArrayList::ArrayList(unsigned int cap) : size(0), capacity(cap) {
//	cout << "Overloaded constructor for ArrayList" << endl;
	store = new Node[ capacity ];
}

ArrayList::~ArrayList() {
//	cout << "Destructor for ArrayList" << endl;
	delete[] store;
}

ArrayList::ArrayList(const ArrayList& source) {
	cout << "Copy constructor for ArrayList" << endl;

}

ArrayList& ArrayList::operator =(const ArrayList& rhs){
	cout << "Assignment operator for ArrayList" << endl;
	if (this == &rhs)
		return *this;

	return *this;
}

void ArrayList::insert(short s, double d){
	if (size < capacity){
		store[size  ].v1 = s;
		store[size++].v2 = d;
	}
}



/*******************************************************************
 * swap - swap the values in the two inputs
 * Preconditions: none
 * Postcondition: v1 == old.v2 && v2 == old.v1
 */
void ArrayList::swapValues(unsigned int i1, unsigned int i2) {
	Node temp = store[i1];
	store[i1] = store[i2];
	store[i2] = temp;
}
/*******************************************************************/


/*******************************************************************
 * indexOfSmallest - find the index of the smallest element in an array
 * Preconditions: size > 0 and a has at least size elements,
 *                0 <= startIndex < size
 * Postcondition: old_value_of_startIndex <= startIndex < size;
 *                The element at a[ startIndex ] will be the smallest
 *                element in the range a[ old_start .. size-1 ]
 */
unsigned int ArrayList::indexOfSmallest( int startIndex ) {
    Node min = store[startIndex];
    int  indexOfMin = startIndex;
    for (unsigned int index = startIndex + 1; index < size; index++)
        if (store[index].v2 < min.v2) {
            min = store[index];
            indexOfMin = index;
            //min is the smallest of store[startIndex] through store[index]
        }

    return indexOfMin;
}
/*******************************************************************/



/*******************************************************************
 * search
 * Precondition: size is <= the declared size of array a.
 * Postcondition:
 * Returns the first index such that a[index] == target,
 * provided there is such an index, otherwise returns -1.
 *
 */
unsigned int ArrayList::search( double target ){
    unsigned int index = 0;
    bool found = false;
    while ((!found) && (index < size))
    if (target == store[index].v2)
        found = true;
    else
        index++;

    if (found)
        return index;
    else
        return -1;
}
/*******************************************************************/

/*******************************************************************
 * sort
 * Preconditions: size <= size of store array
 * Postcondition: values of store[0] through store[size - 1]
 *  are rearranged so that store[0] <= store[1] <= ... <= store[size - 1].
 */
void ArrayList::sort() {
    for (unsigned int index = 0; index < size - 1; index++) {
    	//Place the correct value in store[index]:
    	unsigned int indexOfNextSmallest = indexOfSmallest( index );
        swapValues( index, indexOfNextSmallest );
        //store[0] <= store[1] <=...<= store[index] are the smallest of the original array
        //elements. The rest of the elements are in the remaining positions.
    }
}
/*******************************************************************/


ostream& operator<<(ostream& os, const ArrayList::Node& n){
	os << n.v1 << " " << n.v2;
	return os;
}

ostream& operator<<(ostream& os, const ArrayList& ls){
	for (unsigned int i=0; i<ls.size; i++)
		os << ls.store[i] << endl;
	return os;
}
} /* namespace cs237list */



#include <random> // for random numbers
using std::default_random_engine;
using std::uniform_real_distribution;


namespace cs237list {

/*******************************************************************
 * fillArray - fill an array of Node objects with random values in the v2 double data member
 * Preconditions: None
 * Postcondition: The elements of store will be set to random numbers
 */
void ArrayList::fillRandom(double min, double max) {
	default_random_engine randomEngine;
	uniform_real_distribution<double> uniformDistribution(min , max);

	for ( unsigned int i=0; i<capacity; i++ )
		store[i].v2 = uniformDistribution( randomEngine );

	size=capacity;
	return;
}
/*******************************************************************/

} /* namespace cs237list */
